package com.sqfw.framework.task;

import com.alibaba.fastjson2.JSONObject;
import com.sqfw.common.enums.system.SysBssSignTypeEnum;
import com.sqfw.project.system.domain.SysBssSign;
import com.sqfw.project.system.domain.SysUser;
import com.sqfw.project.system.mapper.SysMenuMapper;
import com.sqfw.project.system.mapper.SysUserMapper;
import com.sqfw.project.system.service.ISysBssSignService;
import com.sqfw.project.utils.HttpClientUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *  用户菜单的签名，验签
 *
 * @author tangxt
 * */
@Component("userMenuSignTask")
@Slf4j
public class UserMenuSignTask {

    private final String PORT_8091 = "8091";

    @Value("${server.port}")
    private String port;

    @Value("${bssSign.apiUrl}")
    private String apiUrl;

    @Value("${bssSign.certAlias}")
    private String certAlias;

    private static final String signDataUrl = "/api/svs/bss/signData";

    private static final String verifySignedDataUrl = "/api/svs/bss/verifySignedData";

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private SysMenuMapper sysMenuMapper;

    @Autowired
    private ISysBssSignService sysBssSignService;

    /**
     * 用户菜单签名
     * */
    public void jobUserMenuSign(String userId) {
        if (!PORT_8091.equals(port)) {
            return;
        }
        List<SysUser> userList = new ArrayList<>();
        SysUser sysUser = new SysUser();
        if (StringUtils.isNotBlank(userId)) {
            log.info("用户菜单签名传递的userId: {}", userId);
            sysUser.setUserId(Long.valueOf(userId));
            userList = sysUserMapper.getUserSignList(sysUser);
        }else {
            userList = sysUserMapper.getUserSignList(sysUser);
        }
        if (!CollectionUtils.isEmpty(userList)) {
            for (SysUser user : userList) {
                List<Long> menuList =  sysMenuMapper.getMenuIdByUserId(user.getUserId());
                if (!CollectionUtils.isEmpty(menuList)) {
                    String originData = menuList.toString();
                    String b64OriginData = Base64.getEncoder().encodeToString(originData.getBytes());
                    Map<String, String> params = new HashMap<>(6);
                    params.put("b64OriginData", b64OriginData);
                    params.put("certAlias", certAlias);
                    log.info("用户菜单签名userId：{}，请求参数params：{}" , user.getUserId(), params.toString());
                    log.info("用户菜单签名请求url： " + apiUrl + signDataUrl);
                    // 调用接口
                    String result = HttpClientUtils.postJson(apiUrl + signDataUrl, params);
                    log.info("用户菜单签名请求接口返回result: " + result);
                    if (StringUtils.isBlank(result)) {
                        log.info("用户菜单请求签名接口失败");
                        return;
                    }else {
                        JSONObject resJson = JSONObject.parseObject(result);
                        // 成功
                        if ("0".equals(resJson.getString("errorCode"))) {
                            String b64SignedData = resJson.getString("b64SignedData");
                            String b64Cert = resJson.getString("b64Cert");
                            SysBssSign queryBssSign = new SysBssSign();
                            queryBssSign.setCorrelationId(user.getUserId().toString());
                            queryBssSign.setDataType(SysBssSignTypeEnum.USER_MENU.getKey());
                            List<SysBssSign> signs = sysBssSignService.selectSysBssSignList(queryBssSign);
                            // 没有签名过
                            if (CollectionUtils.isEmpty(signs)) {
                                SysBssSign sysBssSign = new SysBssSign(user.getUserId().toString(), SysBssSignTypeEnum.USER_MENU.getKey(),
                                        originData, b64OriginData, certAlias, b64SignedData, b64Cert);
                                sysBssSignService.insertSysBssSign(sysBssSign);
                            }else {
                                SysBssSign sysBssSign = new SysBssSign(user.getUserId().toString(), SysBssSignTypeEnum.USER_MENU.getKey(),
                                        originData, b64OriginData, certAlias, b64SignedData, b64Cert);
                                sysBssSign.setId(signs.get(0).getId());
                                sysBssSignService.updateSysBssSign(sysBssSign);
                            }
                        }else {
                            log.error("用户菜单获取失败：" + resJson.getString("errorCode"));
                        }
                    }

                }else {
                    log.info("该用户没有菜单userId：{}", user.getUserId());
                }
            }
        }else {
            log.info("没有获取到用户");
        }
    }

    public void jobUserMenuVerifySign(String userId) {
        if (!PORT_8091.equals(port)) {
            return;
        }
        List<SysUser> userList = new ArrayList<>();
        SysUser sysUser = new SysUser();
        if (StringUtils.isNotBlank(userId)) {
            log.info("用户菜单验签传递的userId: {}", userId);
            sysUser.setUserId(Long.valueOf(userId));
            userList = sysUserMapper.getUserSignList(sysUser);
        }else {
            userList = sysUserMapper.getUserSignList(sysUser);
        }
        if (!CollectionUtils.isEmpty(userList)) {
            for (SysUser user : userList) {
                SysBssSign sysBssSign = new SysBssSign();
                sysBssSign.setCorrelationId(user.getUserId().toString());
                sysBssSign.setDataType(SysBssSignTypeEnum.USER_MENU.getKey());
                List<SysBssSign> signs = sysBssSignService.selectSysBssSignList(sysBssSign);
                if (!CollectionUtils.isEmpty(signs)) {
                    SysBssSign bssSign = signs.get(0);
                    if (StringUtils.isNotBlank(bssSign.getB64Cert())) {
                        List<Long> menuList =  sysMenuMapper.getMenuIdByUserId(user.getUserId());
                        if (!CollectionUtils.isEmpty(menuList)) {
                            String originData = menuList.toString();
                            String b64OriginData = Base64.getEncoder().encodeToString(originData.getBytes());
                            // 调用接口
                            Map<String, String> params = new HashMap<>(16);
                            params.put("b64OriginData", b64OriginData);
                            params.put("b64SignedData", bssSign.getB64SignedData());
                            params.put("b64Cert", bssSign.getB64Cert());
                            log.info("用户菜单验签userId: {}, 请求参数params： {}" + user.getUserId(), params.toString());
                            log.info("用户菜单验签请求url： " + apiUrl + verifySignedDataUrl);
                            // 调用接口
                            String result = HttpClientUtils.postJson(apiUrl + verifySignedDataUrl, params);
                            log.info("用户菜单验签请求接口返回result: " + result);
                            if (StringUtils.isBlank(result)) {
                                log.info("用户菜单验证签名请求接口返回失败");
                                return;
                            }else {
                                JSONObject resJson = JSONObject.parseObject(result);
                                // 成功
                                if (!"0".equals(resJson.getString("errorCode"))) {
                                    sysBssSignService.updateById(bssSign.getId());
                                }
                            }
                        }
                    }
                }else {
                    log.info("该用户菜单没有签名userId：{}", user.getUserId());
                }
            }
        }else {
            log.info("没有查询到用户");
        }
    }

}
